﻿using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using System.Security.Claims;
using System.Text.Encodings.Web;
using WorkLogSystem.Entity;
using WorkLogSystem.Options;

namespace WorkLogSystem.Authentication
{
    public class CustomTokenHandler : AuthenticationHandler<CustomTokenOptions>
    {
        private readonly IMemoryCache _cache;

        public CustomTokenHandler(
            IMemoryCache cache,
            IOptionsMonitor<CustomTokenOptions> options,
            ILoggerFactory logger,
            UrlEncoder encoder,
            ISystemClock clock)
            : base(options, logger, encoder, clock)
        {
            _cache = cache;
        }

        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            if (!Request.Headers.TryGetValue(Options.TokenHeaderName, out var tokenHeaderValues))
            {
                return AuthenticateResult.NoResult();
            }

            var token = tokenHeaderValues.FirstOrDefault();
            if (string.IsNullOrEmpty(token))
            {
                return AuthenticateResult.NoResult();
            }

            if (!_cache.TryGetValue("auth_token_" + token, out UserInfo userInfo))
            {
                return AuthenticateResult.Fail("Invalid token");
            }

            var claims = new[] {
                new Claim("ID", userInfo.ID),
                new Claim("UserName", userInfo.cUserName),
                new Claim("Phone", userInfo.cPhone),
                new Claim("Gender", userInfo.cGender),
                new Claim("Token", token)
            };

            var identity = new ClaimsIdentity(claims, Scheme.Name);
            var principal = new ClaimsPrincipal(identity);
            var ticket = new AuthenticationTicket(principal, Scheme.Name);

            return AuthenticateResult.Success(ticket);
        }
    }
}
